home *** CD-ROM | disk | FTP | other *** search
- /* File strlist.c Copyright (C) 1995, 1996 by John R. Montbriand. All Rights Reserved. */
-
- /* File strlist.c
-
- Copyright (C) 1995, 1996 by John Montbriand. All Rights Reserved.
-
- Distribute freely in areas where the laws of copyright apply.
-
- Use at your own risk.
-
- Do not distribute modified copies.
-
- These various string list libraries are for free!
-
- See the file strlist.txt for details.
-
- */
-
- #include "strlist.h"
- #include <Memory.h>
- #include <StdLib.h>
- #include <OSUtils.h>
- #include <ToolUtils.h>
- #include <String.h>
- #include <Strings.h>
- #include <Resources.h>
- #include <Script.h>
- #include <TextUtils.h>
- #include <StdArg.h>
-
- Handle NewStringList(void) {
- return NewHandleClear(sizeof(short));
- }
-
- Handle MakeStringList(long n, ...) {
- va_list args;
- long i;
- char *s;
- Str255 tempstr;
- Handle list;
- if ((list = NewStringList()) != NULL) {
- va_start(args, n);
- for (i=0; i<n; i++) {
- s = va_arg(args, char*);
- StringListAppend(list, c2pstr(strcpy((char*) tempstr, s)));
- }
- va_end(args);
- }
- return list;
- }
-
- Handle GetStringList(short id) {
- return GetResource('STR#', id);
- }
-
- Handle Get1StringList(short id) {
- return Get1Resource('STR#', id);
- }
-
- short StringListSize(Handle list) {
- if (list == NULL)
- return 0;
- else return ** ((short**) list);
- }
-
- void DisposeStringList(Handle list) {
- char flags;
- if (list != NULL) {
- flags = HGetState(list);
- if ((flags & (1<<5)) != 0) {
- ReleaseResource(list);
- } else {
- DisposeHandle(list);
- }
- }
- }
-
- StringPtr StringListElt(Handle list, short elt) {
- unsigned char *sp;
- short i, n ;
- if (list != NULL) {
- sp = (unsigned char*) (*list);
- n = ** ((short**) list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1)
- if (i==elt) return sp;
- }
- return NULL;
- }
-
- StringPtr RetrieveIndString(Handle list, short elt, StringPtr the_string) {
- StringPtr elt_string;
- elt_string = StringListElt(list, elt);
- if (elt_string != NULL) {
- unsigned char *a, *b;
- long j, n;
- a = elt_string;
- b = the_string;
- for (j = 1, n = (*b++ = *a++); j <= n; j++, *b++ = *a++);
- return the_string;
- } else return NULL;
- }
-
- StringPtr** MakeStringListMap(Handle list) {
- unsigned char *sp;
- short i, n;
- StringPtr** the_array, *rover;
- if (list != NULL) {
- n = ** ((short**) list);
- the_array = (StringPtr**) NewHandle(n * sizeof(StringPtr));
- if (the_array != NULL) {
- MoveHHi(list);
- HLock(list);
- sp = (unsigned char*) (*list);
- rover = *the_array;
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1) *rover++ = sp;
- }
- return the_array;
- } else return NULL;
- }
-
- int STRCompare(const void *a, const void *b) {
- return RelString(* ((StringPtr*) a),* ((StringPtr*) b), SLUSECASE, true);
- }
-
- StringPtr** MakeSortedStringListMap(Handle list) {
- StringPtr** the_map;
- short n;
- the_map = MakeStringListMap(list);
- if (the_map != NULL) {
- n = ** ((short**) list);
- HLock((Handle) the_map);
- qsort(*the_map, n, sizeof(StringPtr), STRCompare);
- HUnlock((Handle) the_map);
- }
- return the_map;
- }
-
- StringPtr MapStringListElt(StringPtr** string_map, short elt) {
- if (string_map != NULL)
- return (*string_map)[elt-1];
- else return NULL;
- }
-
- void StringListRemove(Handle list, short elt) {
- unsigned char *sp, *start;
- short i, n;
- if (list != NULL) {
- n = ** ((short**) list);
- sp = start = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1)
- if (i==elt) {
- Munger(list, sp-start, NULL, *sp + 1, &i, 0);
- (** ((short**) list)) -= 1;
- break;
- }
- }
- }
-
- void ClearStringList(Handle list) {
- if (list != NULL) {
- SetHandleSize(list, 2);
- (** ((short**) list)) = 0;
- }
- }
-
- short StringListInsert(Handle list, StringPtr s) {
- unsigned char *sp, *start;
- short i, n;
- char state;
- if (list != NULL) {
- state = HGetState(list);
- n = ** ((short**) list);
- HLock(list);
- sp = start = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1)
- if (RelString(s, sp, SLUSECASE, true) <= 0) break;
- HUnlock(list);
- Munger(list, sp-start, NULL, 0, s, *s + 1);
- (** ((short**) list)) += 1;
- HSetState(list, state);
- return i;
- } else return 0;
- }
-
- void StringListInstall(Handle list, short elt, StringPtr s) {
- unsigned char *sp, *start;
- short i, n;
- if (list != NULL) {
- n = ** ((short**) list);
- sp = start = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1)
- if (i == elt) break;
- Munger(list, sp-start, NULL, 0, s, *s + 1);
- (** ((short**) list)) += 1;
- }
- }
-
- void StringListAppend(Handle list, StringPtr s) {
- StringListInstall(list, 0x7FFF, s);
- }
-
- void StringListPrepend(Handle list, StringPtr s) {
- StringListInstall(list, 1, s);
- }
-
- short StringListRInsert(Handle list, StringPtr s) {
- unsigned char *sp, *start;
- short i, n;
- char state;
- if (list != NULL) {
- n = ** ((short**) list);
- state = HGetState(list);
- HLock(list);
- sp = start = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1)
- if (RelString(s, sp, false, true) >= 0) break;
- HUnlock(list);
- Munger(list, sp-start, NULL, 0, s, *s + 1);
- (** ((short**) list)) += 1;
- HSetState(list, state);
- return i;
- } else return 0;
- }
-
- short FindStringList(Handle list, StringPtr s) {
- unsigned char *sp, *start;
- short i, n;
- char state;
- if (list != NULL) {
- n = ** ((short**) list);
- state = HGetState(list);
- HLock(list);
- sp = start = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1)
- if (RelString(s, sp, SLUSECASE, true) == 0) break;
- HSetState(list, state);
- return i <= n ? i : 0;
- } else return 0;
- }
-
- MenuHandle StringListToMenu(Handle list, short id, StringPtr name) {
- MenuHandle mnu;
- short i, n;
- char state;
- unsigned char *sp;
- if (list != NULL) {
- n = ** ((short**) list);
- state = HGetState(list);
- HLock(list);
- mnu = NewMenu(id, (name==NULL ? "\pSTR#" : name));
- if (mnu != NULL) {
- sp = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1) {
- #ifdef INTERPRETMENUCHARS
- AppendMenu(mnu, sp);
- #else
- AppendMenu(mnu, "\pDATA");
- SetItem(mnu, i, sp);
- #endif
- }
- }
- HSetState(list, state);
- return mnu;
- } else return NULL;
- }
-
- void StringListToList(Handle list, ListHandle the_list) {
- short i, n;
- char state;
- unsigned char* sp;
- Cell theCell;
- if (list != NULL) {
- n = ** ((short**) list);
- LDelRow(0, 0, the_list);
- LAddRow(StringListSize(list), 0, the_list);
- state = HGetState(list);
- HLock(list);
- sp = (unsigned char*) (*list);
- for (sp+=2, i=1; i<=n; i++, sp += *sp + 1) {
- SetPt(&theCell, 0, i-1);
- LSetCell(sp + 1, sp[0], theCell, the_list);
- }
- HSetState(list, state);
- }
- }
-
-
- Handle StringListUnion(Handle A, Handle B) {
- StringPtr **AMap = NULL, **BMap = NULL, stra, strb;
- Handle result = NULL;
- short acount, bcount, i, j, cmp;
- if ((result = NewStringList()) == NULL) goto union_abort;
- if ((AMap = MakeSortedStringListMap(A)) == NULL) goto union_abort;
- if ((BMap = MakeSortedStringListMap(B)) == NULL) goto union_abort;
- acount = StringListSize(A);
- bcount = StringListSize(B);
- i = j = 0;
- while (i < acount && j < bcount) {
- cmp = RelString((stra = (*AMap)[i]), (strb = (*BMap)[j]),
- SLUSECASE, true);
- if (cmp == 0) {
- StringListAppend(result, stra);
- i++; j++;
- } else if (cmp < 0) {
- StringListAppend(result, stra);
- i++;
- } else {
- StringListAppend(result, strb);
- j++;
- }
- }
- while (i < acount) StringListAppend(result, (*AMap)[i++]);
- while (j < bcount) StringListAppend(result, (*BMap)[j++]);
- DisposeHandle((Handle) AMap); HUnlock(A);
- DisposeHandle((Handle) BMap); HUnlock(B);
- return result;
- union_abort:
- if (AMap != NULL) { DisposeHandle((Handle) AMap); HUnlock(A); }
- if (BMap != NULL) { DisposeHandle((Handle) BMap); HUnlock(B); }
- if (result != NULL) DisposeHandle((Handle) result);
- return NULL;
- }
-
- Handle StringListIntersection(Handle A, Handle B) {
- StringPtr **AMap = NULL, **BMap = NULL, stra, strb;
- Handle result = NULL;
- short acount, bcount, i, j, cmp;
- if ((result = NewStringList()) == NULL) goto union_abort;
- if ((AMap = MakeSortedStringListMap(A)) == NULL) goto union_abort;
- if ((BMap = MakeSortedStringListMap(B)) == NULL) goto union_abort;
- acount = StringListSize(A);
- bcount = StringListSize(B);
- i = j = 0;
- while (i < acount && j < bcount) {
- cmp = RelString((stra = (*AMap)[i]), (strb = (*BMap)[j]),
- SLUSECASE, true);
- if (cmp == 0) {
- StringListAppend(result, stra);
- i++; j++;
- } else if (cmp < 0) i++; else j++;
- }
- DisposeHandle((Handle) AMap); HUnlock(A);
- DisposeHandle((Handle) BMap); HUnlock(B);
- return result;
- union_abort:
- if (AMap != NULL) { DisposeHandle((Handle) AMap); HUnlock(A); }
- if (BMap != NULL) { DisposeHandle((Handle) BMap); HUnlock(B); }
- if (result != NULL) DisposeHandle((Handle) result);
- return NULL;
- }
-
- Handle StringListDifference(Handle A, Handle B) {
- StringPtr **AMap = NULL, **BMap = NULL, stra, strb;
- Handle result = NULL;
- short acount, bcount, i, j, cmp;
- if ((result = NewStringList()) == NULL) goto union_abort;
- if ((AMap = MakeSortedStringListMap(A)) == NULL) goto union_abort;
- if ((BMap = MakeSortedStringListMap(B)) == NULL) goto union_abort;
- acount = StringListSize(A);
- bcount = StringListSize(B);
- i = j = 0;
- while (i < acount && j < bcount) {
- cmp = RelString((stra = (*AMap)[i]), (strb = (*BMap)[j]),
- SLUSECASE, true);
- if (cmp == 0) {
- i++; j++;
- } else if (cmp < 0) {
- StringListAppend(result, stra);
- i++;
- } else {
- StringListAppend(result, strb);
- j++;
- }
- }
- while (i < acount) StringListAppend(result, (*AMap)[i++]);
- while (j < bcount) StringListAppend(result, (*BMap)[j++]);
- DisposeHandle((Handle) AMap); HUnlock(A);
- DisposeHandle((Handle) BMap); HUnlock(B);
- return result;
- union_abort:
- if (AMap != NULL) { DisposeHandle((Handle) AMap); HUnlock(A); }
- if (BMap != NULL) { DisposeHandle((Handle) BMap); HUnlock(B); }
- if (result != NULL) DisposeHandle((Handle) result);
- return NULL;
- }
-
- Boolean StringListSubset(Handle A, Handle B) {
- StringPtr **AMap = NULL, **BMap = NULL, stra, strb;
- Boolean result = true;
- short acount, bcount, i, j, cmp;
- if ((AMap = MakeSortedStringListMap(A)) == NULL) goto union_abort;
- if ((BMap = MakeSortedStringListMap(B)) == NULL) goto union_abort;
- acount = StringListSize(A);
- bcount = StringListSize(B);
- i = j = 0;
- while (i < acount && j < bcount) {
- cmp = RelString((stra = (*AMap)[i]), (strb = (*BMap)[j]),
- SLUSECASE, true);
- if (cmp == 0) { // in both A and B
- i++; j++;
- } else if (cmp < 0) { // in A but not in B
- i++;
- } else { // in B but not in A
- result = false;
- break;
- }
- }
- DisposeHandle((Handle) AMap); HUnlock(A);
- DisposeHandle((Handle) BMap); HUnlock(B);
- return result;
- union_abort:
- if (AMap != NULL) { DisposeHandle((Handle) AMap); HUnlock(A); }
- if (BMap != NULL) { DisposeHandle((Handle) BMap); HUnlock(B); }
- return false;
- }
-
- Boolean StringListEquivalent(Handle A, Handle B) {
- if (StringListSize(A) == StringListSize(B) && StringListSubset(A, B))
- return true;
- else return false;
- }
-
- /* end of file strlist.c */
-